home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 March / macformat-022.iso / Shareware City / Developers / src / out-of-phase-102-c / OutOfPhase 1.02 Source / OutOfPhase Folder / ASTBinaryOperator.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-11-23  |  36.5 KB  |  1,064 lines  |  [TEXT/KAHL]

  1. /* ASTBinaryOperator.c */
  2. /*****************************************************************************/
  3. /*                                                                           */
  4. /*    Out Of Phase:  Digital Music Synthesis on General Purpose Computers    */
  5. /*    Copyright (C) 1994  Thomas R. Lawrence                                 */
  6. /*                                                                           */
  7. /*    This program is free software; you can redistribute it and/or modify   */
  8. /*    it under the terms of the GNU General Public License as published by   */
  9. /*    the Free Software Foundation; either version 2 of the License, or      */
  10. /*    (at your option) any later version.                                    */
  11. /*                                                                           */
  12. /*    This program is distributed in the hope that it will be useful,        */
  13. /*    but WITHOUT ANY WARRANTY; without even the implied warranty of         */
  14. /*    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the          */
  15. /*    GNU General Public License for more details.                           */
  16. /*                                                                           */
  17. /*    You should have received a copy of the GNU General Public License      */
  18. /*    along with this program; if not, write to the Free Software            */
  19. /*    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.              */
  20. /*                                                                           */
  21. /*    Thomas R. Lawrence can be reached at tomlaw@world.std.com.             */
  22. /*                                                                           */
  23. /*****************************************************************************/
  24.  
  25. #include "MiscInfo.h"
  26. #include "Audit.h"
  27. #include "Debug.h"
  28. #include "Definitions.h"
  29.  
  30. #include "ASTBinaryOperator.h"
  31. #include "ASTExpression.h"
  32. #include "TrashTracker.h"
  33. #include "Memory.h"
  34. #include "PromotableTypeCheck.h"
  35.  
  36.  
  37. struct ASTBinaryOpRec
  38.     {
  39.         BinaryOpType                OperationType;
  40.         ASTExpressionRec*        LeftArg;
  41.         ASTExpressionRec*        RightArg;
  42.         long                                LineNumber;
  43.     };
  44.  
  45.  
  46. /* create a new binary operator */
  47. ASTBinaryOpRec*            NewBinaryOperator(BinaryOpType Operation,
  48.                                             struct ASTExpressionRec* LeftArgument,
  49.                                             struct ASTExpressionRec* RightArgument,
  50.                                             struct TrashTrackRec* TrashTracker, long LineNumber)
  51.     {
  52.         ASTBinaryOpRec*        BinaryOp;
  53.  
  54.         CheckPtrExistence(LeftArgument);
  55.         CheckPtrExistence(RightArgument);
  56.         CheckPtrExistence(TrashTracker);
  57.         BinaryOp = (ASTBinaryOpRec*)AllocTrackedBlock(sizeof(ASTBinaryOpRec),TrashTracker);
  58.         if (BinaryOp == NIL)
  59.             {
  60.                 return NIL;
  61.             }
  62.         SetTag(BinaryOp,"ASTBinaryOpRec");
  63.  
  64.         BinaryOp->LineNumber = LineNumber;
  65.         BinaryOp->OperationType = Operation;
  66.         BinaryOp->LeftArg = LeftArgument;
  67.         BinaryOp->RightArg = RightArgument;
  68.  
  69.         return BinaryOp;
  70.     }
  71.  
  72.  
  73. /* do any needed type promotion */
  74. static CompileErrors    PromoteTypeHelper(DataTypes* LeftOperandType,
  75.                                             DataTypes* RightOperandType, ASTBinaryOpRec* BinaryOperator,
  76.                                             long* ErrorLineNumber, struct TrashTrackRec* TrashTracker)
  77.     {
  78.         CompileErrors            Error;
  79.  
  80.         if (CanRightBeMadeToMatchLeft(*LeftOperandType,*RightOperandType)
  81.             && MustRightBePromotedToLeft(*LeftOperandType,*RightOperandType))
  82.             {
  83.                 ASTExpressionRec*        PromotedRightOperand;
  84.  
  85.                 /* we must promote the right operand to become the left operand type */
  86.                 PromotedRightOperand = PromoteTheExpression(*RightOperandType/*orig*/,
  87.                     *LeftOperandType/*desired*/,BinaryOperator->RightArg,
  88.                     BinaryOperator->LineNumber,TrashTracker);
  89.                 if (PromotedRightOperand == NIL)
  90.                     {
  91.                         *ErrorLineNumber = BinaryOperator->LineNumber;
  92.                         return eCompileOutOfMemory;
  93.                     }
  94.                 BinaryOperator->RightArg = PromotedRightOperand;
  95.                 /* sanity check */
  96.                 Error = TypeCheckExpression(RightOperandType/*obtain new right type*/,
  97.                     BinaryOperator->RightArg,ErrorLineNumber,TrashTracker);
  98.                 ERROR((Error != eCompileNoError),PRERR(ForceAbort,
  99.                     "TypeCheckBinaryOperator:  type promotion caused failure"));
  100.                 ERROR(*RightOperandType != *LeftOperandType,PRERR(ForceAbort,
  101.                     "TypeCheckBinaryOperator:  after type promotion, types are no"
  102.                     " longer the same"));
  103.             }
  104.         else if (CanRightBeMadeToMatchLeft(*RightOperandType,*LeftOperandType)
  105.             && MustRightBePromotedToLeft(*RightOperandType,*LeftOperandType))
  106.             {
  107.                 ASTExpressionRec*        PromotedLeftOperand;
  108.  
  109.                 /* we must promote the left operand to become the right operand type */
  110.                 PromotedLeftOperand = PromoteTheExpression(*LeftOperandType/*orig*/,
  111.                     *RightOperandType/*desired*/,BinaryOperator->LeftArg,
  112.                     BinaryOperator->LineNumber,TrashTracker);
  113.                 if (PromotedLeftOperand == NIL)
  114.                     {
  115.                         *ErrorLineNumber = BinaryOperator->LineNumber;
  116.                         return eCompileOutOfMemory;
  117.                     }
  118.                 BinaryOperator->LeftArg = PromotedLeftOperand;
  119.                 /* sanity check */
  120.                 Error = TypeCheckExpression(LeftOperandType/*obtain new left type*/,
  121.                     BinaryOperator->LeftArg,ErrorLineNumber,TrashTracker);
  122.                 ERROR((Error != eCompileNoError),PRERR(ForceAbort,
  123.                     "TypeCheckBinaryOperator:  type promotion caused failure"));
  124.                 ERROR(*RightOperandType != *LeftOperandType,PRERR(ForceAbort,
  125.                     "TypeCheckBinaryOperator:  after type promotion, types are no"
  126.                     " longer the same"));
  127.             }
  128.         return eCompileNoError;
  129.     }
  130.  
  131.  
  132. /* type check the binary operator node.  this returns eCompileNoError if */
  133. /* everything is ok, and the appropriate type in *ResultingDataType. */
  134. CompileErrors                TypeCheckBinaryOperator(DataTypes* ResultingDataType,
  135.                                             ASTBinaryOpRec* BinaryOperator, long* ErrorLineNumber,
  136.                                             struct TrashTrackRec* TrashTracker)
  137.     {
  138.         CompileErrors            Error;
  139.         DataTypes                    LeftOperandType;
  140.         DataTypes                    RightOperandType;
  141.  
  142.         CheckPtrExistence(BinaryOperator);
  143.         CheckPtrExistence(TrashTracker);
  144.  
  145.         Error = TypeCheckExpression(&LeftOperandType,BinaryOperator->LeftArg,
  146.             ErrorLineNumber,TrashTracker);
  147.         if (Error != eCompileNoError)
  148.             {
  149.                 return Error;
  150.             }
  151.  
  152.         Error = TypeCheckExpression(&RightOperandType,BinaryOperator->RightArg,
  153.             ErrorLineNumber,TrashTracker);
  154.         if (Error != eCompileNoError)
  155.             {
  156.                 return Error;
  157.             }
  158.  
  159.         /* do type checking and promotion.  return type determination is deferred */
  160.         switch (BinaryOperator->OperationType)
  161.             {
  162.                 default:
  163.                     EXECUTE(PRERR(ForceAbort,"TypeCheckBinaryOperator:  unknown opcode"));
  164.                     break;
  165.  
  166.                 /* operators capable of boolean, integer, single, double, and fixed args, */
  167.                 /* which return a boolean result */
  168.                 case eBinaryEqual:
  169.                 case eBinaryNotEqual:
  170.                     if (!CanRightBeMadeToMatchLeft(LeftOperandType,RightOperandType)
  171.                         && !CanRightBeMadeToMatchLeft(RightOperandType,LeftOperandType))
  172.                         {
  173.                             *ErrorLineNumber = BinaryOperator->LineNumber;
  174.                             return eCompileTypeMismatch;
  175.                         }
  176.                     ERROR((IsItAScalarType(LeftOperandType) && !IsItAScalarType(RightOperandType))
  177.                         || (!IsItAScalarType(LeftOperandType) && IsItAScalarType(RightOperandType)),
  178.                         PRERR(ForceAbort,"TypeCheckBinaryOperator:  IsItAScalarType error"));
  179.                     if (!IsItAScalarType(LeftOperandType))
  180.                         {
  181.                             *ErrorLineNumber = BinaryOperator->LineNumber;
  182.                             return eCompileOperandsMustBeScalar;
  183.                         }
  184.                     /* do type promotion */
  185.                     Error = PromoteTypeHelper(&LeftOperandType,&RightOperandType,BinaryOperator,
  186.                         ErrorLineNumber,TrashTracker);
  187.                     if (Error != eCompileNoError)
  188.                         {
  189.                             return Error;
  190.                         }
  191.                     break;
  192.  
  193.                 /* operators capable of boolean, integer, and fixed, */
  194.                 /* which return the same type as the arguments */
  195.                 case eBinaryAnd:
  196.                 case eBinaryOr:
  197.                 case eBinaryXor:
  198.                     if ((LeftOperandType != eBoolean) && (LeftOperandType != eInteger)
  199.                         && (LeftOperandType != eFixed))
  200.                         {
  201.                             *ErrorLineNumber = BinaryOperator->LineNumber;
  202.                             return eCompileTypeMismatch;
  203.                         }
  204.                     if (LeftOperandType != RightOperandType)
  205.                         {
  206.                             *ErrorLineNumber = BinaryOperator->LineNumber;
  207.                             return eCompileTypeMismatch;
  208.                         }
  209.                     break;
  210.  
  211.                 /* operators capable of integer, single, double, and fixed args, */
  212.                 /* where the return is the same type as args */
  213.                 case eBinaryPlus:
  214.                 case eBinaryMinus:
  215.                 case eBinaryMultiplication:
  216.                 /* FALL THROUGH! */
  217.  
  218.                 /* operators capable of integer, single, double, and fixed args, */
  219.                 /* where the return is a single, double, or fixed */
  220.                 case eBinaryImpreciseDivision:
  221.                 /* FALL THROUGH! */
  222.  
  223.                 /* operators capable of integer, single, double, and fixed args, */
  224.                 /* which return a boolean */
  225.                 case eBinaryLessThan:
  226.                 case eBinaryLessThanOrEqual:
  227.                 case eBinaryGreaterThan:
  228.                 case eBinaryGreaterThanOrEqual:
  229.                     if (!CanRightBeMadeToMatchLeft(LeftOperandType,RightOperandType)
  230.                         && !CanRightBeMadeToMatchLeft(RightOperandType,LeftOperandType))
  231.                         {
  232.                             *ErrorLineNumber = BinaryOperator->LineNumber;
  233.                             return eCompileTypeMismatch;
  234.                         }
  235.                     ERROR((IsItAScalarType(LeftOperandType) && !IsItAScalarType(RightOperandType))
  236.                         || (!IsItAScalarType(LeftOperandType) && IsItAScalarType(RightOperandType)),
  237.                         PRERR(ForceAbort,"TypeCheckBinaryOperator:  IsItAScalarType error"));
  238.                     if (!IsItASequencedScalarType(LeftOperandType))
  239.                         {
  240.                             *ErrorLineNumber = BinaryOperator->LineNumber;
  241.                             return eCompileOperandsMustBeSequencedScalar;
  242.                         }
  243.                     /* do type promotion */
  244.                     Error = PromoteTypeHelper(&LeftOperandType,&RightOperandType,BinaryOperator,
  245.                         ErrorLineNumber,TrashTracker);
  246.                     if (Error != eCompileNoError)
  247.                         {
  248.                             return Error;
  249.                         }
  250.                     break;
  251.  
  252.                 /* operators capable of integers, returning integer results */
  253.                 case eBinaryIntegerDivision:
  254.                 case eBinaryIntegerRemainder:
  255.                     if ((LeftOperandType != eInteger) || (RightOperandType != eInteger))
  256.                         {
  257.                             *ErrorLineNumber = BinaryOperator->LineNumber;
  258.                             return eCompileOperandsMustBeIntegers;
  259.                         }
  260.                     /* no type promotion is necessary */
  261.                     break;
  262.  
  263.                 /* operators where the left argument must be integer, single, double, fixed */
  264.                 /* and the right argument must be integer, and it returns the same type */
  265.                 /* as the left argument */
  266.                 case eBinaryShiftLeft:
  267.                 case eBinaryShiftRight:
  268.                     if (RightOperandType != eInteger)
  269.                         {
  270.                             *ErrorLineNumber = BinaryOperator->LineNumber;
  271.                             return eCompileRightOperandMustBeInteger;
  272.                         }
  273.                     if (!IsItASequencedScalarType(LeftOperandType))
  274.                         {
  275.                             *ErrorLineNumber = BinaryOperator->LineNumber;
  276.                             return eCompileOperandsMustBeSequencedScalar;
  277.                         }
  278.                     /* DON'T do type promotion */
  279.                     break;
  280.  
  281.                 /* operators where the left argument must be an array and the right */
  282.                 /* argument must be an integer, and the array's element type is returned */
  283.                 case eBinaryArraySubscripting:
  284.                     if (RightOperandType != eInteger)
  285.                         {
  286.                             *ErrorLineNumber = BinaryOperator->LineNumber;
  287.                             return eCompileArraySubscriptMustBeInteger;
  288.                         }
  289.                     if (!IsItAnIndexedType(LeftOperandType))
  290.                         {
  291.                             *ErrorLineNumber = BinaryOperator->LineNumber;
  292.                             return eCompileArrayRequiredForSubscription;
  293.                         }
  294.                     break;
  295.  
  296.                 /* operators where the arguments are double, */
  297.                 /* and which return a double result */
  298.                 case eBinaryExponentiation:
  299.                     if (!CanRightBeMadeToMatchLeft(eDouble,LeftOperandType))
  300.                         {
  301.                             *ErrorLineNumber = BinaryOperator->LineNumber;
  302.                             return eCompileDoubleRequiredForExponentiation;
  303.                         }
  304.                     if (!CanRightBeMadeToMatchLeft(eDouble,RightOperandType))
  305.                         {
  306.                             *ErrorLineNumber = BinaryOperator->LineNumber;
  307.                             return eCompileDoubleRequiredForExponentiation;
  308.                         }
  309.                     /* force the promotion, if necessary */
  310.                     if (LeftOperandType != eDouble)
  311.                         {
  312.                             DataTypes            FakePromotionForcer = eDouble;
  313.  
  314.                             /* promote right operand to double, so left operand is a fake double */
  315.                             Error = PromoteTypeHelper(&LeftOperandType,&FakePromotionForcer,
  316.                                 BinaryOperator,ErrorLineNumber,TrashTracker);
  317.                             if (Error != eCompileNoError)
  318.                                 {
  319.                                     return Error;
  320.                                 }
  321.                             ERROR((FakePromotionForcer != eDouble)
  322.                                 || (LeftOperandType != eDouble),PRERR(ForceAbort,
  323.                                 "TypeCheckBinaryOperator:  exponent ->double promotion failed"));
  324.                         }
  325.                     if (RightOperandType != eDouble)
  326.                         {
  327.                             DataTypes            FakePromotionForcer = eDouble;
  328.  
  329.                             /* promote left operand to double, so right operand is a fake double */
  330.                             Error = PromoteTypeHelper(&FakePromotionForcer,&RightOperandType,
  331.                                 BinaryOperator,ErrorLineNumber,TrashTracker);
  332.                             if (Error != eCompileNoError)
  333.                                 {
  334.                                     return Error;
  335.                                 }
  336.                             ERROR((FakePromotionForcer != eDouble)
  337.                                 || (RightOperandType != eDouble),PRERR(ForceAbort,
  338.                                 "TypeCheckBinaryOperator:  exponent ->double promotion failed"));
  339.                         }
  340.                     break;
  341.  
  342.                 /* operators where left must be an array type and right must be an integer */
  343.                 /* and an array of the same type is returned */
  344.                 case eBinaryResizeArray:
  345.                     if (!IsItAnIndexedType(LeftOperandType))
  346.                         {
  347.                             *ErrorLineNumber = BinaryOperator->LineNumber;
  348.                             return eCompileArrayRequiredForResize;
  349.                         }
  350.                     if (RightOperandType != eInteger)
  351.                         {
  352.                             *ErrorLineNumber = BinaryOperator->LineNumber;
  353.                             return eCompileIntegerRequiredForResize;
  354.                         }
  355.                     break;
  356.             }
  357.  
  358.         /* now, figure out what the return type should be */
  359.         switch (BinaryOperator->OperationType)
  360.             {
  361.                 default:
  362.                     EXECUTE(PRERR(ForceAbort,"TypeCheckBinaryOperator:  unknown opcode"));
  363.                     break;
  364.  
  365.                 /* operators capable of boolean, integer, single, double, and fixed args, */
  366.                 /* which return a boolean result */
  367.                 case eBinaryEqual:
  368.                 case eBinaryNotEqual:
  369.                     ERROR(LeftOperandType != RightOperandType,PRERR(ForceAbort,
  370.                         "TypeCheckBinaryOperator:  operand types are not equivalent but should be"));
  371.                     ERROR(!IsItAScalarType(LeftOperandType),PRERR(ForceAbort,
  372.                         "TypeCheckBinaryOperator:  operand types are not scalar but should be"));
  373.                     *ResultingDataType = eBoolean;
  374.                     break;
  375.  
  376.                 /* operators capable of boolean, integer, single, double, and fixed args, */
  377.                 /* which return the same type as the arguments */
  378.                 case eBinaryAnd:
  379.                 case eBinaryOr:
  380.                 case eBinaryXor:
  381.                     ERROR(LeftOperandType != RightOperandType,PRERR(ForceAbort,
  382.                         "TypeCheckBinaryOperator:  operand types are not equivalent but should be"));
  383.                     ERROR((LeftOperandType != eBoolean) && (LeftOperandType != eInteger)
  384.                         && (LeftOperandType != eFixed),PRERR(ForceAbort,
  385.                         "TypeCheckBinaryOperator:  operand types are not what they should be"));
  386.                     *ResultingDataType = LeftOperandType;
  387.                     break;
  388.  
  389.                 /* operators capable of integer, single, double, and fixed args, */
  390.                 /* where the return is the same type as args */
  391.                 case eBinaryPlus:
  392.                 case eBinaryMinus:
  393.                 case eBinaryMultiplication:
  394.                     ERROR(LeftOperandType != RightOperandType,PRERR(ForceAbort,
  395.                         "TypeCheckBinaryOperator:  operand types are not equivalent but should be"));
  396.                     ERROR(!IsItASequencedScalarType(LeftOperandType),PRERR(ForceAbort,
  397.                         "TypeCheckBinaryOperator:  operand types are not seq scalar but should be"));
  398.                     *ResultingDataType = LeftOperandType;
  399.                     break;
  400.  
  401.                 /* operators capable of integer, single, double, and fixed args, */
  402.                 /* where the return is a single, double, or fixed */
  403.                 case eBinaryImpreciseDivision:
  404.                     ERROR(LeftOperandType != RightOperandType,PRERR(ForceAbort,
  405.                         "TypeCheckBinaryOperator:  operand types are not equivalent but should be"));
  406.                     ERROR(!IsItASequencedScalarType(LeftOperandType),PRERR(ForceAbort,
  407.                         "TypeCheckBinaryOperator:  operand types are not seq scalar but should be"));
  408.                     if (LeftOperandType != eInteger)
  409.                         {
  410.                             *ResultingDataType = LeftOperandType;
  411.                         }
  412.                      else
  413.                         {
  414.                             *ResultingDataType = eDouble;
  415.                         }
  416.                     break;
  417.  
  418.                 /* operators capable of integer, single, double, and fixed args, */
  419.                 /* which return a boolean */
  420.                 case eBinaryLessThan:
  421.                 case eBinaryLessThanOrEqual:
  422.                 case eBinaryGreaterThan:
  423.                 case eBinaryGreaterThanOrEqual:
  424.                     ERROR(LeftOperandType != RightOperandType,PRERR(ForceAbort,
  425.                         "TypeCheckBinaryOperator:  operand types are not equivalent but should be"));
  426.                     ERROR(!IsItAScalarType(LeftOperandType),PRERR(ForceAbort,
  427.                         "TypeCheckBinaryOperator:  operand types are not scalar but should be"));
  428.                     *ResultingDataType = eBoolean;
  429.                     break;
  430.  
  431.                 /* operators capable of integers, returning integer results */
  432.                 case eBinaryIntegerDivision:
  433.                 case eBinaryIntegerRemainder:
  434.                     ERROR((LeftOperandType != eInteger) || (RightOperandType != eInteger),
  435.                         PRERR(ForceAbort,"TypeCheckBinaryOperator:  operands should be integers"));
  436.                     *ResultingDataType = eInteger;
  437.                     break;
  438.  
  439.                 /* operators where the left argument must be integer, single, double, fixed */
  440.                 /* and the right argument must be integer, and it returns the same type */
  441.                 /* as the left argument */
  442.                 case eBinaryShiftLeft:
  443.                 case eBinaryShiftRight:
  444.                     ERROR(RightOperandType != eInteger,PRERR(ForceAbort,
  445.                         "TypeCheckBinaryOperator:  right operand should be integer"));
  446.                     ERROR(!IsItASequencedScalarType(LeftOperandType),PRERR(ForceAbort,
  447.                         "TypeCheckBinaryOperator:  left operand should be seq scalar"));
  448.                     *ResultingDataType = LeftOperandType;
  449.                     break;
  450.  
  451.                 /* operators where the left argument must be an array and the right */
  452.                 /* argument must be an integer, and the array's element type is returned */
  453.                 case eBinaryArraySubscripting:
  454.                     ERROR(RightOperandType != eInteger,PRERR(ForceAbort,
  455.                         "TypeCheckBinaryOperator:  right operand should be integer"));
  456.                     switch (LeftOperandType)
  457.                         {
  458.                             default:
  459.                                 EXECUTE(PRERR(ForceAbort,"TypeCheckBinaryOperator:  spurious type "
  460.                                     "occurred after array subscript typecheck filter"));
  461.                                 break;
  462.                             case eArrayOfBoolean:
  463.                                 *ResultingDataType = eBoolean;
  464.                                 break;
  465.                             case eArrayOfInteger:
  466.                                 *ResultingDataType = eInteger;
  467.                                 break;
  468.                             case eArrayOfFloat:
  469.                                 *ResultingDataType = eFloat;
  470.                                 break;
  471.                             case eArrayOfDouble:
  472.                                 *ResultingDataType = eDouble;
  473.                                 break;
  474.                             case eArrayOfFixed:
  475.                                 *ResultingDataType = eFixed;
  476.                                 break;
  477.                         }
  478.                     break;
  479.  
  480.                 /* operators where the arguments are double, */
  481.                 /* and which return a double result */
  482.                 case eBinaryExponentiation:
  483.                     ERROR((LeftOperandType != eDouble) || (RightOperandType != eDouble),
  484.                         PRERR(ForceAbort,"TypeCheckBinaryOperator:  operands should be double"));
  485.                     *ResultingDataType = eDouble;
  486.                     break;
  487.  
  488.                 /* operators where left must be an array type and right must be an integer */
  489.                 /* and an array of the same type is returned */
  490.                 case eBinaryResizeArray:
  491.                     ERROR(!IsItAnIndexedType(LeftOperandType),PRERR(ForceAbort,
  492.                         "TypeCheckBinaryOperator:  operand should be array"));
  493.                     ERROR(RightOperandType != eInteger,PRERR(ForceAbort,
  494.                         "TypeCheckBinaryOperator:  operand should be integer"));
  495.                     *ResultingDataType = LeftOperandType;
  496.                     break;
  497.             }
  498.  
  499.         return eCompileNoError;
  500.     }
  501.  
  502.  
  503. /* find out just what kind of binary operation this is */
  504. BinaryOpType                BinaryOperatorWhichOne(ASTBinaryOpRec* TheBinOp)
  505.     {
  506.         CheckPtrExistence(TheBinOp);
  507.         return TheBinOp->OperationType;
  508.     }
  509.  
  510.  
  511. /* get the left hand side operand out of a binary operator record */
  512. struct ASTExpressionRec*    GetLeftOperandForBinaryOperator(ASTBinaryOpRec* TheBinOp)
  513.     {
  514.         CheckPtrExistence(TheBinOp);
  515.         return TheBinOp->LeftArg;
  516.     }
  517.  
  518.  
  519. /* get the right hand side operand out of a binary operator record */
  520. struct ASTExpressionRec*    GetRightOperandForBinaryOperator(ASTBinaryOpRec* TheBinOp)
  521.     {
  522.         CheckPtrExistence(TheBinOp);
  523.         return TheBinOp->RightArg;
  524.     }
  525.  
  526.  
  527. /* generate code for a binary operator.  returns True if successful, or False if it fails. */
  528. MyBoolean                        CodeGenBinaryOperator(struct PcodeRec* FuncCode,
  529.                                             long* StackDepthParam, ASTBinaryOpRec* BinaryOperator)
  530.     {
  531.         long                            StackDepth;
  532.         Pcodes                        Opcode;
  533.  
  534.         CheckPtrExistence(FuncCode);
  535.         CheckPtrExistence(BinaryOperator);
  536.         StackDepth = *StackDepthParam;
  537.  
  538.         /* generate code for left operand */
  539.         if (!CodeGenExpression(FuncCode,&StackDepth,BinaryOperator->LeftArg))
  540.             {
  541.                 return False;
  542.             }
  543.         ERROR(StackDepth != *StackDepthParam + 1,PRERR(ForceAbort,
  544.             "CodeGenBinaryOperator:  stack depth error on left operand"));
  545.  
  546.         /* generate code for the right operand */
  547.         if (!CodeGenExpression(FuncCode,&StackDepth,BinaryOperator->RightArg))
  548.             {
  549.                 return False;
  550.             }
  551.         ERROR(StackDepth != *StackDepthParam + 2,PRERR(ForceAbort,
  552.             "CodeGenBinaryOperator:  stack depth error on right operand"));
  553.  
  554.         /* generate the opcode for performing the computation */
  555.         switch (BinaryOperator->OperationType)
  556.             {
  557.                 default:
  558.                     EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator:  unknown opcode"));
  559.                     break;
  560.  
  561.                 case eBinaryAnd:
  562.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg)
  563.                         != GetExpressionsResultantType(BinaryOperator->LeftArg),
  564.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryAnd]:  "
  565.                         "type check failure -- operands are not the same type"));
  566.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  567.                         {
  568.                             default:
  569.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryAnd]:  "
  570.                                     "bad operand types"));
  571.                                 break;
  572.                             case eBoolean:
  573.                                 Opcode = epOperationBooleanAnd;
  574.                                 break;
  575.                             case eInteger:
  576.                                 Opcode = epOperationIntegerAnd;
  577.                                 break;
  578.                             case eFixed:
  579.                                 Opcode = epOperationFixedAnd;
  580.                                 break;
  581.                         }
  582.                     break;
  583.  
  584.                 case eBinaryOr:
  585.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg)
  586.                         != GetExpressionsResultantType(BinaryOperator->LeftArg),
  587.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryOr]:  "
  588.                         "type check failure -- operands are not the same type"));
  589.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  590.                         {
  591.                             default:
  592.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryOr]:  "
  593.                                     "bad operand types"));
  594.                                 break;
  595.                             case eBoolean:
  596.                                 Opcode = epOperationBooleanOr;
  597.                                 break;
  598.                             case eInteger:
  599.                                 Opcode = epOperationIntegerOr;
  600.                                 break;
  601.                             case eFixed:
  602.                                 Opcode = epOperationFixedOr;
  603.                                 break;
  604.                         }
  605.                     break;
  606.  
  607.                 case eBinaryXor:
  608.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg)
  609.                         != GetExpressionsResultantType(BinaryOperator->LeftArg),
  610.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryXor]:  "
  611.                         "type check failure -- operands are not the same type"));
  612.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  613.                         {
  614.                             default:
  615.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryXor]:  "
  616.                                     "bad operand types"));
  617.                                 break;
  618.                             case eBoolean:
  619.                                 Opcode = epOperationBooleanXor;
  620.                                 break;
  621.                             case eInteger:
  622.                                 Opcode = epOperationIntegerXor;
  623.                                 break;
  624.                             case eFixed:
  625.                                 Opcode = epOperationFixedXor;
  626.                                 break;
  627.                         }
  628.                     break;
  629.  
  630.                 case eBinaryLessThan:
  631.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg)
  632.                         != GetExpressionsResultantType(BinaryOperator->LeftArg),
  633.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryLessThan]:  "
  634.                         "type check failure -- operands are not the same type"));
  635.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  636.                         {
  637.                             default:
  638.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryLessThan]:  "
  639.                                     "bad operand types"));
  640.                                 break;
  641.                             case eInteger:
  642.                                 Opcode = epOperationIntegerLessThan;
  643.                                 break;
  644.                             case eFloat:
  645.                                 Opcode = epOperationFloatLessThan;
  646.                                 break;
  647.                             case eDouble:
  648.                                 Opcode = epOperationDoubleLessThan;
  649.                                 break;
  650.                             case eFixed:
  651.                                 Opcode = epOperationFixedLessThan;
  652.                                 break;
  653.                         }
  654.                     break;
  655.  
  656.                 case eBinaryLessThanOrEqual:
  657.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg)
  658.                         != GetExpressionsResultantType(BinaryOperator->LeftArg),
  659.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryLessThanOrEqual]:  "
  660.                         "type check failure -- operands are not the same type"));
  661.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  662.                         {
  663.                             default:
  664.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryLessThanOrEqual]:  "
  665.                                     "bad operand types"));
  666.                                 break;
  667.                             case eInteger:
  668.                                 Opcode = epOperationIntegerLessThanOrEqual;
  669.                                 break;
  670.                             case eFloat:
  671.                                 Opcode = epOperationFloatLessThanOrEqual;
  672.                                 break;
  673.                             case eDouble:
  674.                                 Opcode = epOperationDoubleLessThanOrEqual;
  675.                                 break;
  676.                             case eFixed:
  677.                                 Opcode = epOperationFixedLessThanOrEqual;
  678.                                 break;
  679.                         }
  680.                     break;
  681.  
  682.                 case eBinaryGreaterThan:
  683.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg)
  684.                         != GetExpressionsResultantType(BinaryOperator->LeftArg),
  685.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryGreaterThan]:  "
  686.                         "type check failure -- operands are not the same type"));
  687.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  688.                         {
  689.                             default:
  690.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryGreaterThan]:  "
  691.                                     "bad operand types"));
  692.                                 break;
  693.                             case eInteger:
  694.                                 Opcode = epOperationIntegerGreaterThan;
  695.                                 break;
  696.                             case eFloat:
  697.                                 Opcode = epOperationFloatGreaterThan;
  698.                                 break;
  699.                             case eDouble:
  700.                                 Opcode = epOperationDoubleGreaterThan;
  701.                                 break;
  702.                             case eFixed:
  703.                                 Opcode = epOperationFixedGreaterThan;
  704.                                 break;
  705.                         }
  706.                     break;
  707.  
  708.                 case eBinaryGreaterThanOrEqual:
  709.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg)
  710.                         != GetExpressionsResultantType(BinaryOperator->LeftArg),
  711.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryGreaterThanOrEqual]:  "
  712.                         "type check failure -- operands are not the same type"));
  713.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  714.                         {
  715.                             default:
  716.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryGreaterThanOrEqual]:  "
  717.                                     "bad operand types"));
  718.                                 break;
  719.                             case eInteger:
  720.                                 Opcode = epOperationIntegerGreaterThanOrEqual;
  721.                                 break;
  722.                             case eFloat:
  723.                                 Opcode = epOperationFloatGreaterThanOrEqual;
  724.                                 break;
  725.                             case eDouble:
  726.                                 Opcode = epOperationDoubleGreaterThanOrEqual;
  727.                                 break;
  728.                             case eFixed:
  729.                                 Opcode = epOperationFixedGreaterThanOrEqual;
  730.                                 break;
  731.                         }
  732.                     break;
  733.  
  734.                 case eBinaryEqual:
  735.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg)
  736.                         != GetExpressionsResultantType(BinaryOperator->LeftArg),
  737.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryEqual]:  "
  738.                         "type check failure -- operands are not the same type"));
  739.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  740.                         {
  741.                             default:
  742.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryEqual]:  "
  743.                                     "bad operand types"));
  744.                                 break;
  745.                             case eBoolean:
  746.                                 Opcode = epOperationBooleanEqual;
  747.                                 break;
  748.                             case eInteger:
  749.                                 Opcode = epOperationIntegerEqual;
  750.                                 break;
  751.                             case eFloat:
  752.                                 Opcode = epOperationFloatEqual;
  753.                                 break;
  754.                             case eDouble:
  755.                                 Opcode = epOperationDoubleEqual;
  756.                                 break;
  757.                             case eFixed:
  758.                                 Opcode = epOperationFixedEqual;
  759.                                 break;
  760.                         }
  761.                     break;
  762.  
  763.                 case eBinaryNotEqual:
  764.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg)
  765.                         != GetExpressionsResultantType(BinaryOperator->LeftArg),
  766.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryNotEqual]:  "
  767.                         "type check failure -- operands are not the same type"));
  768.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  769.                         {
  770.                             default:
  771.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryNotEqual]:  "
  772.                                     "bad operand types"));
  773.                                 break;
  774.                             case eBoolean:
  775.                                 Opcode = epOperationBooleanNotEqual;
  776.                                 break;
  777.                             case eInteger:
  778.                                 Opcode = epOperationIntegerNotEqual;
  779.                                 break;
  780.                             case eFloat:
  781.                                 Opcode = epOperationFloatNotEqual;
  782.                                 break;
  783.                             case eDouble:
  784.                                 Opcode = epOperationDoubleNotEqual;
  785.                                 break;
  786.                             case eFixed:
  787.                                 Opcode = epOperationFixedNotEqual;
  788.                                 break;
  789.                         }
  790.                     break;
  791.  
  792.                 case eBinaryPlus:
  793.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg)
  794.                         != GetExpressionsResultantType(BinaryOperator->LeftArg),
  795.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryPlus]:  "
  796.                         "type check failure -- operands are not the same type"));
  797.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  798.                         {
  799.                             default:
  800.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryPlus]:  "
  801.                                     "bad operand types"));
  802.                                 break;
  803.                             case eInteger:
  804.                                 Opcode = epOperationIntegerAdd;
  805.                                 break;
  806.                             case eFloat:
  807.                                 Opcode = epOperationFloatAdd;
  808.                                 break;
  809.                             case eDouble:
  810.                                 Opcode = epOperationDoubleAdd;
  811.                                 break;
  812.                             case eFixed:
  813.                                 Opcode = epOperationFixedAdd;
  814.                                 break;
  815.                         }
  816.                     break;
  817.  
  818.                 case eBinaryMinus:
  819.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg)
  820.                         != GetExpressionsResultantType(BinaryOperator->LeftArg),
  821.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryMinus]:  "
  822.                         "type check failure -- operands are not the same type"));
  823.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  824.                         {
  825.                             default:
  826.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryMinus]:  "
  827.                                     "bad operand types"));
  828.                                 break;
  829.                             case eInteger:
  830.                                 Opcode = epOperationIntegerSubtract;
  831.                                 break;
  832.                             case eFloat:
  833.                                 Opcode = epOperationFloatSubtract;
  834.                                 break;
  835.                             case eDouble:
  836.                                 Opcode = epOperationDoubleSubtract;
  837.                                 break;
  838.                             case eFixed:
  839.                                 Opcode = epOperationFixedSubtract;
  840.                                 break;
  841.                         }
  842.                     break;
  843.  
  844.                 case eBinaryMultiplication:
  845.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg)
  846.                         != GetExpressionsResultantType(BinaryOperator->LeftArg),
  847.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryMultiplication]:  "
  848.                         "type check failure -- operands are not the same type"));
  849.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  850.                         {
  851.                             default:
  852.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryMultiplication]:  "
  853.                                     "bad operand types"));
  854.                                 break;
  855.                             case eInteger:
  856.                                 Opcode = epOperationIntegerMultiply;
  857.                                 break;
  858.                             case eFloat:
  859.                                 Opcode = epOperationFloatMultiply;
  860.                                 break;
  861.                             case eDouble:
  862.                                 Opcode = epOperationDoubleMultiply;
  863.                                 break;
  864.                             case eFixed:
  865.                                 Opcode = epOperationFixedMultiply;
  866.                                 break;
  867.                         }
  868.                     break;
  869.  
  870.                 case eBinaryImpreciseDivision:
  871.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg)
  872.                         != GetExpressionsResultantType(BinaryOperator->LeftArg),
  873.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryImpreciseDivision]:  "
  874.                         "type check failure -- operands are not the same type"));
  875.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  876.                         {
  877.                             default:
  878.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryImpreciseDivision]:  "
  879.                                     "bad operand types"));
  880.                                 break;
  881.                             case eInteger:
  882.                                 Opcode = epOperationIntegerImpreciseDivide;
  883.                                 break;
  884.                             case eFloat:
  885.                                 Opcode = epOperationFloatDivide;
  886.                                 break;
  887.                             case eDouble:
  888.                                 Opcode = epOperationDoubleDivide;
  889.                                 break;
  890.                             case eFixed:
  891.                                 Opcode = epOperationFixedDivide;
  892.                                 break;
  893.                         }
  894.                     break;
  895.  
  896.                 case eBinaryIntegerDivision:
  897.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg)
  898.                         != GetExpressionsResultantType(BinaryOperator->LeftArg),
  899.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryIntegerDivision]:  "
  900.                         "type check failure -- operands are not the same type"));
  901.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  902.                         {
  903.                             default:
  904.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryIntegerDivision]:  "
  905.                                     "bad operand types"));
  906.                                 break;
  907.                             case eInteger:
  908.                                 Opcode = epOperationIntegerDivide;
  909.                                 break;
  910.                         }
  911.                     break;
  912.  
  913.                 case eBinaryIntegerRemainder:
  914.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg)
  915.                         != GetExpressionsResultantType(BinaryOperator->LeftArg),
  916.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryIntegerRemainder]:  "
  917.                         "type check failure -- operands are not the same type"));
  918.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  919.                         {
  920.                             default:
  921.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryIntegerRemainder]:  "
  922.                                     "bad operand types"));
  923.                                 break;
  924.                             case eInteger:
  925.                                 Opcode = epOperationIntegerModulo;
  926.                                 break;
  927.                         }
  928.                     break;
  929.  
  930.                 case eBinaryShiftLeft:
  931.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg) != eInteger,
  932.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryShiftLeft]:  "
  933.                         "type check failure -- right operand isn't an integer"));
  934.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  935.                         {
  936.                             default:
  937.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryShiftLeft]:  "
  938.                                     "bad operand types"));
  939.                                 break;
  940.                             case eInteger:
  941.                                 Opcode = epOperationIntegerShiftLeft;
  942.                                 break;
  943.                             case eFloat:
  944.                                 Opcode = epOperationFloatShiftLeft;
  945.                                 break;
  946.                             case eDouble:
  947.                                 Opcode = epOperationDoubleShiftLeft;
  948.                                 break;
  949.                             case eFixed:
  950.                                 Opcode = epOperationFixedShiftLeft;
  951.                                 break;
  952.                         }
  953.                     break;
  954.  
  955.                 case eBinaryShiftRight:
  956.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg) != eInteger,
  957.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryShiftRight]:  "
  958.                         "type check failure -- right operand isn't an integer"));
  959.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  960.                         {
  961.                             default:
  962.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryShiftRight]:  "
  963.                                     "bad operand types"));
  964.                                 break;
  965.                             case eInteger:
  966.                                 Opcode = epOperationIntegerShiftRight;
  967.                                 break;
  968.                             case eFloat:
  969.                                 Opcode = epOperationFloatShiftRight;
  970.                                 break;
  971.                             case eDouble:
  972.                                 Opcode = epOperationDoubleShiftRight;
  973.                                 break;
  974.                             case eFixed:
  975.                                 Opcode = epOperationFixedShiftRight;
  976.                                 break;
  977.                         }
  978.                     break;
  979.  
  980.                 case eBinaryArraySubscripting:
  981.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg) != eInteger,
  982.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryArraySubscripting]:  "
  983.                         "type check failure -- right operand isn't an integer"));
  984.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  985.                         {
  986.                             default:
  987.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryArraySubscripting]:  "
  988.                                     "bad operand types"));
  989.                                 break;
  990.                             case eArrayOfBoolean:
  991.                                 Opcode = epLoadBooleanFromArray2;
  992.                                 break;
  993.                             case eArrayOfInteger:
  994.                                 Opcode = epLoadIntegerFromArray2;
  995.                                 break;
  996.                             case eArrayOfFloat:
  997.                                 Opcode = epLoadFloatFromArray2;
  998.                                 break;
  999.                             case eArrayOfDouble:
  1000.                                 Opcode = epLoadDoubleFromArray2;
  1001.                                 break;
  1002.                             case eArrayOfFixed:
  1003.                                 Opcode = epLoadFixedFromArray2;
  1004.                                 break;
  1005.                         }
  1006.                     break;
  1007.  
  1008.                 case eBinaryExponentiation:
  1009.                     ERROR((GetExpressionsResultantType(BinaryOperator->RightArg) != eDouble)
  1010.                         || (GetExpressionsResultantType(BinaryOperator->LeftArg) != eDouble),
  1011.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryExponentiation]:  "
  1012.                         "type check failure -- an argument isn't a double"));
  1013.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  1014.                         {
  1015.                             default:
  1016.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryExponentiation]:  "
  1017.                                     "bad operand types"));
  1018.                                 break;
  1019.                             case eDouble:
  1020.                                 Opcode = epOperationDoublePower;
  1021.                                 break;
  1022.                         }
  1023.                     break;
  1024.  
  1025.                 case eBinaryResizeArray:
  1026.                     ERROR(GetExpressionsResultantType(BinaryOperator->RightArg) != eInteger,
  1027.                         PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryResizeArray]:  "
  1028.                         "type check failure -- right operand isn't an integer"));
  1029.                     switch (GetExpressionsResultantType(BinaryOperator->LeftArg))
  1030.                         {
  1031.                             default:
  1032.                                 EXECUTE(PRERR(ForceAbort,"CodeGenBinaryOperator[eBinaryResizeArray]:  "
  1033.                                     "bad operand types"));
  1034.                                 break;
  1035.                             case eArrayOfBoolean:
  1036.                                 Opcode = epResizeBooleanArray2;
  1037.                                 break;
  1038.                             case eArrayOfInteger:
  1039.                                 Opcode = epResizeIntegerArray2;
  1040.                                 break;
  1041.                             case eArrayOfFloat:
  1042.                                 Opcode = epResizeFloatArray2;
  1043.                                 break;
  1044.                             case eArrayOfDouble:
  1045.                                 Opcode = epResizeDoubleArray2;
  1046.                                 break;
  1047.                             case eArrayOfFixed:
  1048.                                 Opcode = epResizeFixedArray2;
  1049.                                 break;
  1050.                         }
  1051.                     break;
  1052.             }
  1053.         if (!AddPcodeInstruction(FuncCode,Opcode,NIL))
  1054.             {
  1055.                 return False;
  1056.             }
  1057.         StackDepth -= 1;
  1058.         ERROR(StackDepth != *StackDepthParam + 1,PRERR(ForceAbort,
  1059.             "CodeGenBinaryOperator:  post operator stack size is screwed up"));
  1060.  
  1061.         *StackDepthParam = StackDepth;
  1062.         return True;
  1063.     }
  1064.